#include "CManagerTag.h"
#include <iostream>
CManagerTag::CManagerTag(IObservadorTag* tagsManager){
	this->tagsManager = tagsManager;
	this->tagId = 0;
}

CManagerTag::~CManagerTag(){
	if(!this->tagFile.is_open()){
		this->tagFile.close();
	}
}

bool CManagerTag::crearTag(DBFrecuencias::TagId id){
	if(this->tagFile.is_open()){
		this->tagFile.close();
	}
	std::stringstream ss;
	std::string file;
	ss << id;
	ss >> file;
	file = DB_TAG + file + ".dat";
	this->tagFile.open(file.c_str(), std::ios::out | std::ios::binary | std::ios::ate | std::ios::trunc);
	this->tagId = id;
	this->tagFile.close();
	return true;
}

/**
 * Este metodo se llama si en el adm del archivo, se intenta agregar una frecuencia
 * y esa frecuencia no esta en el registro
 * 
 */
void CManagerTag::insertarPalabra(DBFrecuencias::TagId tag, DBFrecuencias::Palabra palabra){
	if(this->chequearEstado(tag)){
		this->tagFile.seekp(0,std::ios::end);
		unsigned int longitud = palabra.length();
		this->tagFile.write(reinterpret_cast<const char*>(&longitud),sizeof(unsigned int));
		this->tagFile.write(reinterpret_cast<const char*>(palabra.c_str()),longitud);
	}
}
	
/**
 * Este metodo se llama, si se decrementa la frecuencia de una palabra lo suficiente como
 * para que sea 0
 */
void CManagerTag::eliminarPalabra(DBFrecuencias::TagId tag, DBFrecuencias::Palabra palabra){
	DBFrecuencias::Palabra id;
	std::stringstream ss;
	std::string file;
	ss << tag;
	ss >> file;
	file = DB_TAG + file + ".dat";
	std::list<std::string> lista;
	if(this->chequearEstado(tag)){
		this->tagFile.seekg(0, std::ios::beg);
		while((!this->tagFile.eof())
				&&(this->tagFile.peek()!=std::ios::traits_type::eof())){
			unsigned int longitud;
			std::string id;
			this->tagFile.read(reinterpret_cast<char*>(&longitud),sizeof(unsigned int));
			char* buffer = new char[longitud+1];
			this->tagFile.read(reinterpret_cast<char*>(buffer),longitud);
			buffer[longitud]='\0';
			id.assign(buffer);
			delete[] buffer;
			if(palabra.compare(id) != 0){
					lista.push_back(id);
			}
		}
		this->tagFile.close();
		truncate(file.c_str(), 0);
		for(std::list<std::string>::iterator it = lista.begin() ; it != lista.end() ;it++){
			this->insertarPalabra(tag,*it);
		}
	}
}

bool CManagerTag::eof(){
	bool eof = (this->tagFile.eof() ||(this->tagFile.peek()==std::ios::traits_type::eof()) );
	if(eof){
		this->tagFile.clear();
	} 
	return eof;	
}
	
bool CManagerTag::abrirTag(DBFrecuencias::TagId tag){
	return this->chequearEstado(tag);
}
	
DBFrecuencias::Palabra CManagerTag::leerPalabra(){
	DBFrecuencias::Palabra id;
	unsigned int longitud;
	this->tagFile.read(reinterpret_cast<char*>(&longitud),sizeof(unsigned int));
	char* buffer = new char[longitud+1];
	this->tagFile.read(reinterpret_cast<char*>(buffer),longitud);
	buffer[longitud]='\0';
	id.assign(buffer);
	
	delete[] buffer;
	return id;
}

bool CManagerTag::chequearEstado(DBFrecuencias::TagId tag){
	std::stringstream ss;
	std::string file;
	ss << tag;
	ss >> file;
	file = DB_TAG + file + ".dat";
	if(this->tagId != tag){
		if(this->tagFile.is_open())
			this->tagFile.close();
		this->tagId = tag;
	}
	if(this->tagId == tag){
		if(!this->tagFile.is_open()){
			this->tagFile.open(file.c_str(),std::ios::out | std::ios::binary | std::ios::in | std::ios::ate);
		}
	}
	this->tagFile.seekg(0,std::ios::beg);
	return this->tagFile.is_open();
}

void CManagerTag::eliminarTag(DBFrecuencias::TagId tag){
	this->dbFrecuencias->eliminarTag(tag);
	std::stringstream ss;
	std::string file;
	ss << tag;
	ss >> file;
	file = DB_TAG + file + ".dat";
	if((this->tagFile.is_open())&&(this->tagId==tag)){
		this->tagFile.close();
	}
	unlink(file.c_str());
}

void CManagerTag::incrementarNumeroPalabras(DBFrecuencias::TagId tag,DBFrecuencias::Frecuencia frec){
	this->tagsManager->incrementarNumeroPalabras(tag,frec);
}

void CManagerTag::decrementarNumeroPalabras(DBFrecuencias::TagId tag, DBFrecuencias::Frecuencia frec){
	this->tagsManager->decrementarNumeroPalabras(tag,frec);
}
